package com.agentframework.core.action;

import com.agentframework.core.agent.Agent;
import com.agentframework.core.agent.AgentHolder;
import com.agentframework.core.environment.AbstractEnvironment;
import com.agentframework.core.provider.Llm;
import com.agentframework.core.provider.LlmType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.lang.NonNull;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 抽象智能体动作基类
 * @author wangjun
 **/
public abstract class AbstractAction implements Action, ApplicationContextAware, InitializingBean {

    protected static final Logger logger = LoggerFactory.getLogger(AbstractAction.class);

    protected final String actionName;

    protected int order;

    protected Llm llm;
    protected LlmType llmType;
    protected ApplicationContext applicationContext;

    protected AbstractAction(String actionName) {
        this(actionName, LlmType.DEEPSEEK, 0);
    }

    protected AbstractAction(String actionName, LlmType llmType) {
        this(actionName, llmType, 0);
    }

    protected AbstractAction(String actionName, int order) {
        this(actionName, LlmType.DEEPSEEK, order);
    }

    protected AbstractAction(String actionName, LlmType llmType, int order) {
        this.actionName = actionName;
        this.llmType = llmType;
        this.order = order;
    }

    @Override
    public AssistantMessage execute(String message) {
        return execute(List.of(new UserMessage(message)));
    }

    @Override
    public AssistantMessage execute(List<Message> messages) {
        return (AssistantMessage) llm.call(doExecute(messages));
    }

    @Override
    public String name() {
        return getActionName();
    }

    @Override
    public int getOrder() {
        return this.order;
    }

    public void setOrder(int order) {
        this.order = order;
    }

    protected Prompt doExecute(List<Message> messages) {
        List<Message> promptMessages = new ArrayList<>();
        if (StringUtils.hasText(getFormatInstruction())) {
            promptMessages.add(new SystemMessage(getFormatInstruction()));
        }
        promptMessages.addAll(messages);
        return new Prompt(promptMessages);
    }

    /**
     * 由子类覆盖，可以自定义提示词
     * @return prompt
     */
    protected String getFormatInstruction() {
        return "";
    }

    protected Agent getAgent() {
        return AgentHolder.getAgent();
    }

    protected List<Message> getNews() {
        return getAgent().getContext().getNews();
    }

    protected List<Message> getHistory() {
        return llm.getChatMemory().get(getAgent().getContext().getEnvironment().getEnvId());
    }

    protected void publishMessage(Message message) {
        getAgent().getContext().getEnvironment().publishMessage(message);
    }

    protected AbstractEnvironment getEnvironment() {
        return getAgent().getContext().getEnvironment();
    }

    public String getActionName() {
        return this.actionName;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.llm = applicationContext.getBean(Llm.class);
    }

    @Override
    public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public String toString() {
        return "Action{" +
                "name='" + actionName + '\'' +
                ", order='" + order + '\'' +
                '}';
    }

}
